package se.webbzon.oschi01.action;

import java.awt.Component;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.IOException;

import javax.swing.Icon;
import javax.swing.JOptionPane;

import se.webbzon.oschi01.command.Command;
import se.webbzon.oschi01.command.UndoableClipboard;
import se.webbzon.oschi01.gui.ApplicationIconSheet;
import se.webbzon.oschi01.gui.ApplicationIcon;
import se.webbzon.oschi01.gui.NBTTransferable;
import se.webbzon.oschi01.nbt.Tag;
import se.webbzon.oschi01.nbt.TagGeneration;
import se.webbzon.oschi01.singleton.Singletons;

public class NBTPasteAction extends DefaultAction {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 7507684222090545849L;

	private static final ApplicationIconSheet iconSheet = Singletons.instance(ApplicationIconSheet.class);
	
	private final Component parent;
	private final Tag<?> nbtTag;
	private final UndoableClipboard clipboard;
	
	public NBTPasteAction(Component parent, Tag<?> nbtTag, UndoableClipboard clipboard) {
		this.parent = parent;
		this.nbtTag = nbtTag;
		this.clipboard = clipboard;
		putValue(NAME, "Paste");
		putValue(SMALL_ICON, iconSheet.getIcon(ApplicationIcon.Paste));
		setEnabled(clipboard.getContents(null) != null);
	}

	@Override public void actionPerformed(ActionEvent event) {
		try {
			Transferable t = clipboard.getContents(null);
			if (t != null) {
				Object o = t.getTransferData(NBTTransferable.dataFlavor);
				if (o instanceof NBTTransferable) {
					NBTTransferable nbtTransferable = (NBTTransferable) o; 
					Tag<?> copy = nbtTransferable.clone().getRoot();
					if (nbtTag.canAdopt(copy)) {
						performCommand(new CommandImpl(nbtTag.getChildren(),copy));
					} else if (!nbtTag.hasChildren() && nbtTag.hasParent() && nbtTag.getParent().canAdopt(copy)) {
						performCommand(new CommandImpl(nbtTag.getGeneration(),copy));
					} else {
						String message = "The content of the clipboard can not be pasted into the target.";
						String title = "Action not supported";
						int messageType = JOptionPane.PLAIN_MESSAGE;
						Icon icon = iconSheet.getIcon(ApplicationIcon.Error);
						JOptionPane.showMessageDialog(parent, message, title, messageType, icon);
					}
				}
			}
		} catch (IllegalStateException | IOException | UnsupportedFlavorException e) {
			// Do nothing
		}
	}
	
	private static final class CommandImpl implements Command {
		
		private final TagGeneration<?> target;
		@SuppressWarnings("rawtypes")
		private final Tag copy;
		
		public CommandImpl(TagGeneration<?> target, Tag<?> copy) {
			this.target = target;
			this.copy = copy;
		}
		
		@Override public String getName() {
			return "paste " + copy;
		}

		@SuppressWarnings("unchecked")
		@Override public void redo() {
			target.addSibling(copy);
		}

		@SuppressWarnings("unchecked")
		@Override public void undo() {
			target.removeSibling(copy);
		}
		
	}

}
